/**
 * @description 登录、获取用户信息、退出登录、清除token逻辑，不建议修改
 */
import { defineStore } from 'pinia'
import { getUserInfo, login as baseLogin } from '@/api/sysUser'
import { tokenName } from '@/config'
import { getToken, removeToken, setToken } from '@/utils/token'
import type { UserInfoType } from '@/types/userInfo'

export const useUserStore = defineStore('user', {
  state: (): { userInfo: UserInfoType; nickName: string; avatar: string; token: string } => ({
    token: getToken() as string,
    nickName: '游客',
    avatar: './favicon.svg',
    userInfo: <UserInfoType>{},
  }),
  getters: {
    getToken: (state) => state.token,
    getUsername: (state) => state.nickName,
    getAvatar: (state) => state.avatar,
  },
  actions: {
    /**
     * @description 设置token
     * @param {*} token
     */
    setToken(token: string) {
      this.token = token
      setToken(token)
    },
    /**
     * @description 设置用户名
     * @param {*} nickName
     */
    setUsername(nickName: string) {
      this.nickName = nickName
    },
    /**
     * @description 设置头像
     * @param {*} avatar
     */
    setAvatar(avatar: string) {
      this.avatar = avatar
    },
    /**
     * @description 登录拦截放行时，设置虚拟角色
     */
    setVirtualRoles() {
      this.setUsername('admin(未开启登录拦截)')
      this.setAvatar('./favicon.svg')
    },
    /**
     *
     * @description 设置用户信息
     * @param {*} userInfo
     */
    setUserInfo(userInfo: UserInfoType) {
      this.userInfo = userInfo
    },
    /**
     * @description 设置token并发送提醒
     * @param {string} token 更新令牌
     * @param {string} tokenName 令牌名称
     */
    afterLogin(token: string, tokenName: string) {
      if (token) {
        this.setToken(token)
      } else {
        const err = `登录接口异常，未正确返回${tokenName}...`
        throw err
      }
    },
    /**
     * @description 登录
     * @param {*} userInfo
     */
    async login(userInfo: any) {
      const {
        data: { [tokenName]: token },
      } = await baseLogin(userInfo)
      this.afterLogin(token, tokenName)
    },
    /**
     * @description 获取用户信息接口 这个接口非常非常重要，如果没有明确底层前逻辑禁止修改此方法，错误的修改可能造成整个框架无法正常使用
     * @returns
     */
    async getUserInfo() {
      const { data } = await getUserInfo()
      const { nickName, avatar, roles, realName } = data
      /**
       * 检验返回数据是否正常，无对应参数，将使用默认用户名,头像,Roles和Permissions
       * nickName {String}
       * avatar {String}
       * roles {List}
       * ability {List}
       */
      this.setUsername(nickName ?? realName)
      // 如不使用avatar头像,可删除以下代码
      if (avatar) this.setAvatar(avatar)
      // 如不使用roles权限控制,可删除以下代码
      // // 如不使用permissions权限控制,可删除以下代码
      // if (permissions) aclStore.setPermission(permissions)
      // 设置用户信息
      if (data) this.setUserInfo(data)
    },
    /**
     * @description 退出登录
     */
    async logout() {
      // await logout()
      await this.resetAll()
      location.reload()
    },
    /**
     * @description 重置token、roles、permission、router、tabsBar等
     */
    async resetAll() {
      await removeToken()
      this.setToken('')
      this.setUsername('游客')
      this.setAvatar('./favicon.svg')
    },
  },
})
